package books.storage.util;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import books.storage.dto.AuthorDto;
import books.storage.dto.BookDto;
import books.storage.dto.LiteraryGenreDto;
import books.storage.eao.BookManagerEao;
import books.storage.eao.BooksStorageEao;
import books.storage.entity.AuthorEntity;
import books.storage.entity.BookEntity;
import books.storage.entity.LiteraryGenreEntity;
import books.storage.exception.EntityNotFoundException;
import books.storage.util.jpa.Entity;

/**
 * Session Bean implementation class Conversion
 */
@Stateless
@LocalBean
public class Conversion {

	@EJB
	BookManagerEao beao;

	@EJB
	BooksStorageEao eao;

	/**
	 * Default constructor.
	 */
	public Conversion() {
	}

	public Conversion(BooksStorageEao eao, BookManagerEao beao) {
		this.eao = eao;
		this.beao = beao;
	}

	// FROM ENTITY

	public LiteraryGenreDto fromLiteraryGenreEntity(LiteraryGenreEntity genre) {
		LiteraryGenreDto result = new LiteraryGenreDto();

		result.setWording(genre.getWording());
		result.setDescription(genre.getDescription());

		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : genre.getBooks()) {
			books.add(this.fromBookEntity(book));
		}

		result.setBooks(books);
		result.setId(genre.getId());

		return result;
	}

	public BookDto fromBookEntity(BookEntity book) {
		BookDto result = new BookDto();

		result.setCopiesNumber(book.getCopiesNumber());
		result.setEditionDate(book.getEditionDate());
		result.setLiterary(this.fromLiteraryGenreEntity(book
				.getLiteraryGenre()));
		result.setTitle(book.getTitle());
		result.setAuthor(this.fromAuthorEntity(book.getAuthor()));
		result.setIsbn(book.getIsbn());
		result.setId(book.getId());
		
		return result;
	}

	public AuthorDto fromAuthorEntity(AuthorEntity author) {
		AuthorDto result = new AuthorDto();

		result.setBirthday(author.getBirthday());
		result.setDeathday(author.getDeathday());
		result.setName(author.getName());

		List<BookDto> books = new ArrayList<>();
		for (BookEntity book : author.getBooks()) {
			books.add(this.fromBookEntity(book));
		}

		result.setBooks(books);
		result.setId(author.getId());

		return result;
	}

	// FROM DTO

	public LiteraryGenreEntity fromLiteraryGenreDto(LiteraryGenreDto _genre)
			throws EntityNotFoundException {

		LiteraryGenreEntity result;
		Integer id = _genre.getId();

		if (Entity.isId(id))
			result = eao.findOrFail(LiteraryGenreEntity.class, id);
		else
			result = new LiteraryGenreEntity();

		result.setWording(_genre.getWording());
		result.setDescription(_genre.getDescription());

		List<BookEntity> books = new ArrayList<>();

		if (_genre.getBooks() != null)
			for (BookDto book : _genre.getBooks()) {
				books.add(eao.findOrFail(BookEntity.class, book.getId()));
			}

		result.setBooks(books);
		result.setId(_genre.getId());

		return result;
	}

	public AuthorEntity fromAuthorDto(AuthorDto _author)
			throws EntityNotFoundException {

		AuthorEntity result;
		Integer id = _author.getId();

		if (Entity.isId(id))
			result = eao.findOrFail(AuthorEntity.class, id);
		else
			result = new AuthorEntity();

		result.setBirthday(_author.getBirthday());
		result.setDeathday(_author.getDeathday());
		result.setName(_author.getName());

		List<BookEntity> books = new ArrayList<>();

		if (_author.getBooks() != null)
			for (BookDto book : _author.getBooks()) {
				books.add(eao.findOrFail(BookEntity.class, book.getId()));
			}

		result.setBooks(books);
		result.setId(_author.getId());

		return result;
	}

	public BookEntity fromBookDto(BookDto _book) throws EntityNotFoundException {

		BookEntity result;
		Integer id = _book.getId();

		if (Entity.isId(id))
			result = eao.findOrFail(BookEntity.class, id);
		else
			result = new BookEntity();

		result.setIsbn(_book.getIsbn());
		result.setCopiesNumber(_book.getCopiesNumber());
		result.setEditionDate(_book.getEditionDate());
		result.setTitle(_book.getTitle());
		result.setId(_book.getId());
		
		result.setAuthor(eao.findOrFail(AuthorEntity.class, _book.getAuthor()
				.getId()));
		result.setLiteraryGenre(eao.findOrFail(LiteraryGenreEntity.class, _book
				.getLiterary().getId()));

		return result;
	}
}
